﻿using System;
using System.Net;
using System.Windows;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Diagnostics;
using System.Collections.Generic;

public class VnSharing
{
    public const string SOURCE = "http://truyen.vnsharing.net/";
    public const int MANGAID = 1;

    //public struct ChapterInfo
    //{
    //    public string Link;
    //    public string Name;
    //};


    public MangaInfo GetMangaInfo(string content)
    {
        MangaInfo manga = new MangaInfo();

        // parse TITLE
        manga.Tilte = ParseTitle(content);

        // parse GENRES
        manga.Genres = ParseGenres(content);

        // parse AUTHORS
        manga.Authors = ParseAuthors(content);

        // parse TRANSLATORGROUP
        manga.TranslatorGroup = ParseTranslatorGroup(content);

        // parse LINKS 
        manga.Links = ParseLinks(content);
        // parse CHAPTERS
        manga.Chapters = ParseChapters(content);

        // parse SUMMARY
        manga.Summary = ParseSummary(content);

        // parse STATUS
        manga.Status = ParseStatus(content);

        // parse VIEW 
        manga.Views = ParseView(content);

        // parse IMAGELINK
        manga.ImageLink = ParseImageLink(content);

        return manga;
    }

    private IList<ChapterInfo> ParseChapters(string content)
    {
        // (href[^>]*TacGia[^>]*>)([^<]*)
        string links = @"\<(a[\s]*href)[^>]*(/Truyen/[^(?="")|(\\)]*)[^>]*title[^>]*>[^(\s)]*[\s]*([^<]*)";
        // (/Truyen/[^(?="")|(\\)]*): get link of chapter, [^(?="")|(\\)]*: any char except " (quote), \ (bakcsplash)
        // after first close tag >, check all char to first char of title
        // get chapter title by using ([^<]*)
        Regex linksRegex = new Regex(links, RegexOptions.IgnoreCase);
        MatchCollection linksMatchCollection = linksRegex.Matches(content);

        // for test
        for (int index = 0; index < linksMatchCollection.Count; index++)
        {
            Debug.WriteLine(linksMatchCollection[index].Value);
        }

        if (linksMatchCollection.Count > 0)
        {
            IList<ChapterInfo> linksValues = new List<ChapterInfo>() ;
            // if manga is oneshot, it may have one link (doesn't have continous chapter) so index may be in 0-1
            // dont need to minus 1 for count of oneshot manga
            // old version: for (int indexOfAuthorsMatches = 0; indexOfAuthorsMatches < linksMatchCollection.Count - 1; indexOfAuthorsMatches++)
            // new version
            int countLinksMatch = linksMatchCollection.Count;
            if (countLinksMatch > 1)
                countLinksMatch--;

            // minus 1 for linksMatch because the last one is not available for downloading
            // old version: for (int indexOfAuthorsMatches = 0; indexOfAuthorsMatches < linksMatchCollection.Count - 1; indexOfAuthorsMatches++)
            for (int indexOfAuthorsMatches = 0; indexOfAuthorsMatches < countLinksMatch; indexOfAuthorsMatches++)
            {
                Match linksMatch = linksMatchCollection[indexOfAuthorsMatches];
                GroupCollection linksGroups = linksMatch.Groups;
                if (linksGroups.Count >= 1) // if it's in right way, it must have 3 groups
                {
                    // for test 
                    foreach (Group testGroup in linksGroups)
                    {
                        Debug.WriteLine(testGroup.Value);
                        Debug.WriteLine("-----");
                    }

                    ChapterInfo newChap = new ChapterInfo();
                    newChap.Link = "http://truyen.vnsharing.net" + linksGroups[linksGroups.Count - 2].Value;
                    newChap.Title = linksGroups[linksGroups.Count - 1].Value;
                    linksValues.Add(newChap);
                }
            }
            return linksValues;
        }
        return null;
    }

    private string ParseImageLink(string content)
    {
        string pattern = @"<(img\s+width)\b[^>]*>";

        Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
        Match match = rgx.Match(content);

        string patternReturn = @"(?<="")http.+?(?="")";
        Regex rgxReturn = new Regex(patternReturn, RegexOptions.IgnoreCase);
        Match matchReturn = rgxReturn.Match(match.Value);

        return matchReturn.Value;
    }

    private int ParseView(string content)
    {
        string summary = @"(xem:[^>]*>)[\s]*([^(\\\r)|<|\s]*)";
        Regex summaryRegex = new Regex(summary, RegexOptions.IgnoreCase);
        Match summaryMatch = summaryRegex.Match(content);
        GroupCollection summaryGroups = summaryMatch.Groups;

        // for test groups value
        foreach (Group testGroup in summaryGroups)
        {
            Debug.WriteLine(testGroup.Value);
            Debug.WriteLine("-----");
        }

        if (summaryGroups.Count > 1)
        {
            // Chưa xử lý HTMLTag ở đuôi của Summary
            try
            {
                int valueReturn = int.Parse(summaryGroups[summaryGroups.Count - 1].Value);
                return valueReturn;
            }
            catch
            {
                return 0;
            }
            
        }
        return 0;
    }

    private string ParseSummary(string content)
    {
        //string summary = @"Sơ lược:</span>\s*<p[\s\w\d""'’=+%/&?\-;]*[^>]*>([\(\)""&/\s\’<\>\%\$\?\[\]\{\}\,\!\@\#\*\d\w:;'=+\-\.\\]*)[^(</p>)]</p>";
        string summary = @"(Sơ lược:</span>)[^(<p>)]*<p>([^<]*)";
        Regex summaryRegex = new Regex(summary, RegexOptions.IgnoreCase);
        Match summaryMatch = summaryRegex.Match(content);
        GroupCollection summaryGroups = summaryMatch.Groups;
        
        // for test groups value
        foreach (Group testGroup in summaryGroups)
        {
            Debug.WriteLine(testGroup.Value);
            Debug.WriteLine("-----");
        }

        if (summaryGroups.Count > 1)
        {
                // Chưa xử lý HTMLTag ở đuôi của Summary
                return summaryGroups[summaryGroups.Count - 1].Value;
        }
        return "";
    }

    private string[] ParseLinks(string content)
    {
        // (href[^>]*TacGia[^>]*>)([^<]*)
        string links = @"\<(a\s+href)[^>]*(/Truyen/[^(?="")|(\\)]*)[^>]*title";
        Regex linksRegex = new Regex(links, RegexOptions.IgnoreCase);
        MatchCollection linksMatchCollection = linksRegex.Matches(content);

        // for test
        for (int index = 0; index < linksMatchCollection.Count; index++)
        {
            Debug.WriteLine(linksMatchCollection[index].Value);
        }

        if (linksMatchCollection.Count > 0)
        {
            string[] linksValues = new string[linksMatchCollection.Count - 1];

            // minus 1 for linksMatch because the last one is not available for downloading
            for (int indexOfAuthorsMatches = 0; indexOfAuthorsMatches < linksMatchCollection.Count - 1; indexOfAuthorsMatches++)
            {
                Match linksMatch = linksMatchCollection[indexOfAuthorsMatches];
                GroupCollection linksGroups = linksMatch.Groups;
                if (linksGroups.Count >= 1)
                {
                    linksValues[indexOfAuthorsMatches] = linksGroups[linksGroups.Count - 1].Value;
                }
            }
            return linksValues;
        }
        return null;
    }

    private string ParseStatus(string content)
    {
        // @"(Sơ lược:</span>)[^(<p>)]*<p>([^<]*)";
        // <span class=\"info\">Tình trạng:</span> Tạm ngưng\r\n 
        string status = @"(Tình trạng:[^>]*>)([^(\\\r)|<]*)";
        Regex statusRegex = new Regex(status, RegexOptions.IgnoreCase);
        Match statusMatch = statusRegex.Match(content);
        GroupCollection statusGroups = statusMatch.Groups;

        foreach (Group testGroup in statusGroups)
        {
            Debug.WriteLine(testGroup.Value);
            Debug.WriteLine("-----");
        }

        if (statusGroups.Count > 1)
        {
            return statusGroups[statusGroups.Count - 1].Value;
        }
        return "";
    }

    private string ParseTranslatorGroup(string content)
    {
        string translator = @"(href[^>]*Nhom[^>]*>)([^<]*)";
        Regex translatorRegex = new Regex(translator, RegexOptions.IgnoreCase);
        Match translatorMatch = translatorRegex.Match(content);
        GroupCollection translatorGroups = translatorMatch.Groups;
        if (translatorGroups.Count > 1)
            return translatorGroups[translatorGroups.Count - 1].Value;
        return "";
    }

    private string[] ParseAuthors(string content)
    {

        // (href[^>]*TacGia[^>]*>)([^<]*)
        string authors = @"(href[^>]*TacGia[^>]*>)([^<]*)";
        Regex authorsRegex = new Regex(authors, RegexOptions.IgnoreCase);
        MatchCollection authorsMatchCollection = authorsRegex.Matches(content);
        if (authorsMatchCollection.Count > 0)
        {
            string[] authorsValues = new string[authorsMatchCollection.Count];

            for (int indexOfAuthorsMatches = 0; indexOfAuthorsMatches < authorsMatchCollection.Count; indexOfAuthorsMatches++)
            {
                Match genresMatch = authorsMatchCollection[indexOfAuthorsMatches];
                GroupCollection genresGroups = genresMatch.Groups;
                if (genresGroups.Count >= 1)
                {
                    authorsValues[indexOfAuthorsMatches] = genresGroups[genresGroups.Count - 1].Value;
                }
            }
            return authorsValues;
        }
        return null;
    }

    private string[] ParseGenres(string content)
    {
        string genres = @"(TheLoai/)([a-z0-9]*)";
        Regex genresRegex = new Regex(genres, RegexOptions.IgnoreCase);
        MatchCollection genresMatchCollection = genresRegex.Matches(content);
        if (genresMatchCollection.Count > 0)
        {
            string[] genresValues = new string[genresMatchCollection.Count];

            for (int indexOfGenresMatches = 0; indexOfGenresMatches < genresMatchCollection.Count; indexOfGenresMatches++)
            {
                Match genresMatch = genresMatchCollection[indexOfGenresMatches];
                GroupCollection genresGroups = genresMatch.Groups;
                if (genresGroups.Count >= 3)
                {
                    genresValues[indexOfGenresMatches] = genresGroups[genresGroups.Count - 1].Value;
                }
            }
            return genresValues;
        }
        return null;
    }

    private string ParseTitle(string content)
    {
        string title = @"(bigChar[^>]*>)([^><]*)";
        Regex titleRegex = new Regex(title, RegexOptions.IgnoreCase);
        Match tilteMatch = titleRegex.Match(content);
        GroupCollection titleGroups = tilteMatch.Groups;
        if (titleGroups.Count > 1)
            return titleGroups[titleGroups.Count - 1].Value;
        return "";
    }

    /// <summary>
    /// Get chapter information (link & name) from html text
    /// </summary>
    /// <param name="result"></param>
    /// <param name="mangaName"></param>
    /// <returns>List of ChapterInfo</returns>
    //public List<ChapterInfo> GetChapterLinks(string content, string mangaName)
    //{
    //    // get list of match have "href"
    //    //string pattern = @"<(a\s+href)\b[^>]*>\b[^>]*>"; // <a/space*n/href/string/>string> // chuan
    //    string pattern = @"\<(a\s+href)[^>]*(/Truyen/[^(?="")|(\\)]*)";
    //    // <a  href=\"/Truyen/Kami-no-mizo-Shiru-Sekai/Flag-149\" title=\"Đọc Kami nomi zo Shiru Sekai Flag. 149 - Chuyện về m&#236;nh online\">\r\n Kami nomi zo Shiru Sekai Flag. 149 - Chuyện về mình</a>

    //    Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
    //    MatchCollection matches = rgx.Matches(content);

    //    List<ChapterInfo> chapters = new List<ChapterInfo>();

    //    // for test
    //    for (int index = 0; index < matches.Count; index++)
    //    {
    //        Debug.WriteLine(matches[index].Value);
    //    }

    //    Debug.WriteLine("--------------------------------------");



    //    int NumberOfChapter = matches.Count;

    //    for (int index = 0, l = matches.Count; index < l; index++)
    //    {
    //        // Get match which has chapter link
    //        string search = @"(?<="")/Truyen/" + mangaName + @"/.+?(?="")"; // get content inside "content" // /Truyen/mangaName/string = content
    //        Regex regex = new Regex(search, RegexOptions.IgnoreCase);
    //        Match chapterLink = regex.Match(matches[index].Value);


    //        // insert match into List of ChapterInfo
    //        if (chapterLink.Value != "")
    //        {
    //            //Debug.WriteLine(chapterLink.Value);
    //            ChapterInfo chap = new ChapterInfo();
    //            chap.Link = chapterLink.Value;


    //            //string searchName = @"(?<=>).+?(?=<)";
    //            ////string searchName = @"\\r\\n.+?";
    //            //Regex rgxName = new Regex(searchName, RegexOptions.IgnoreCase);
    //            string value = matches[index].Value;
    //            //Debug.WriteLine(value.LastIndexOf("\r\n").ToString());
    //            //Debug.WriteLine(value.Substring(value.LastIndexOf("   ") + 3, value.LastIndexOf("<") - (value.LastIndexOf("   ") + 3)));
    //            //string test = value.Substring(value.LastIndexOf("\r\n"));

    //            //Match name = rgxName.Match(value);
    //            chap.Name = value.Substring(value.LastIndexOf("   ") + 3, value.LastIndexOf("<") - (value.LastIndexOf("   ") + 3));
    //            //if (name.Value.Length > 0)
    //            //{
    //            //    chap.Name = name.Value.Substring(5);
    //            //}
    //            //else
    //            //{
    //            //    chap.Name = chap.Link.Substring(chap.Link.LastIndexOf("/") + 1);
    //            //}
    //            //chap.Name = String.Format("Chapter {0}", NumberOfChapter.ToString("D3"));
    //            //NumberOfChapter--;
    //            chapters.Add(chap);
    //        }
    //    }

    //    // remove external countinued chapter
    //    chapters.RemoveAt(chapters.Count - 1);

    //    chapters.Reverse();
    //    // for test
    //    for (int index = 0; index < chapters.Count; index++)
    //    {
    //        Debug.WriteLine(chapters[index].Link + " - " + chapters[index].Name);
    //    }

    //    return chapters;
    //}

    public List<string> GetImageLinks(string content)
    {
        string search = @"(?<="")http://images2-focus-opensocial.+?(?="")";

        Regex rgx = new Regex(search, RegexOptions.IgnoreCase);
        MatchCollection matches = rgx.Matches(content);
        List<string> returnValue = new List<string>();
        if (matches.Count > 0)
        {
            for (int index = 0; index < matches.Count; index++)
            {
                returnValue.Add(matches[index].Value);
            }
            return returnValue;
        }

        return null;
    }

    public string GetImage(string result)
    {
        string pattern = @"<(img\s+width)\b[^>]*>";

        Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
        Match match = rgx.Match(result);

        string patternReturn = @"(?<="")http.+?(?="")";
        Regex rgxReturn = new Regex(patternReturn, RegexOptions.IgnoreCase);
        Match matchReturn = rgxReturn.Match(match.Value);

        return matchReturn.Value;
    }


    public IList<string> GetImageLinksOfChapter(string downloadedContent)
    {
        string search = @"(?<="")http://images2-focus-opensocial.+?(?="")";

        Regex rgx = new Regex(search, RegexOptions.IgnoreCase);
        MatchCollection matches = rgx.Matches(downloadedContent);
        IList<string> returnValue = new List<string>();
        if (matches.Count > 0)
        {
            for (int index = 0; index < matches.Count; index++)
            {
                returnValue.Add(matches[index].Value);
            }
            return returnValue;
        }

        return null;
        
    }

    public List<MangaInfo> GetMangaList(string downloadedContent, ref int totalPages)
    {
        List<MangaInfo> tmpList = new List<MangaInfo>();

        // 
        // @"\<a\s+class[^>]*href=""(/Truyen/[^(?="")|(\\)|/]*)(?=""))"; ->   <a href="/Truyen/Air-Gear_truyenkyvn"
        // @"\<a\s+href=""(/Truyen/[^(?="")|(\\)|/]*)[(?="")|(\\)|/]" ->   <a href="/Truyen/Air-Gear_truyenkyvn" and  <a href="/Truyen/Air-Gear_truyenkyvn/
        string links = @"\<a\s+class[^>]*href=""(/Truyen/[^(?="")|(\\)|/]*)""[^>]*>([^<]*)";
        Regex linksRegex = new Regex(links, RegexOptions.IgnoreCase);
        MatchCollection linksMatchCollection = linksRegex.Matches(downloadedContent);
        // for test
        foreach (Match matchTest in linksMatchCollection)
        {
            //Debug.WriteLine(matchTest.Value);
            GroupCollection groupsTest = matchTest.Groups;
            //Debug.WriteLine("---- " + groupsTest[1].Value + " ---- " + groupsTest[2].Value);
            MangaInfo tmpManga = new MangaInfo();
            tmpManga.LinkManga = "http://truyen.vnsharing.net" + groupsTest[1].Value;
            tmpManga.Tilte = groupsTest[2].Value;

            tmpList.Add(tmpManga);
        }

        string search = @"page=[^>]*[0-9]*";
        Regex regex = new Regex(search, RegexOptions.IgnoreCase);
        MatchCollection matches = regex.Matches(downloadedContent);
        //Match chapterLink = regex.Match(result);

        //foreach (Match match in matches)
        //{
        //    Debug.WriteLine(match.Value);
        //}

        if (matches.Count > 0)
        {
            string lastResult = matches[matches.Count - 1].Value;
            string pattern = @"(\+|-)?[0-9][0-9]*(\.[0-9]*)?";
            Regex reg = new Regex(pattern);
            Match match = reg.Match(lastResult);
            //MatchCollection matches11 = reg.Matches(lastResult, 0);

            if (match != null)
                totalPages =  int.Parse(match.Value);
        }


        return tmpList;
    }
}

